<script setup lang="ts">
  import { PropType, ref, watch } from 'vue'
  import { FormInstance } from 'element-plus'
  import { FieldForm } from '../types'
  import _ from 'lodash'

  const props = defineProps({
    modalTitle: {
      type: String,
      required: true,
    },
    isAdd: {
      type: Boolean,
      required: true,
    },
    form: {
      type: Object as PropType<FieldForm>,
      required: true,
    },
    modelValue: {
      type: Boolean,
      default: () => false,
    },
  })

  const emits = defineEmits<{
    (e: 'updated', value: FieldForm): void
    (e: 'update:modelValue', value: boolean): void
  }>()

  // 字段类型下拉选项
  const fieldTypeOptions = ref([
    { name: '文本', val: 1 },
    { name: '多行文本', val: 2 },
    { name: '单选', val: 3 },
    { name: '多选', val: 4 },
    { name: '多图', val: 5 },
    { name: '附件', val: 6 },
    { name: '视频', val: 7 },
    { name: '评分', val: 8 },
    { name: '日期', val: 9 },
    { name: '日期时间', val: 10 },
  ])

  // 表单
  const __form = ref<FieldForm>({
    type: 1,
    contentVos: [
      {
        id: '',
        val: '',
      },
    ],
    delContentIds: [],
    id: null,
    uploadSize: 100,
    name: '',
    required: true,
    sort: 0,
    status: false, //false-启用，true-禁用
    tip: '',
    uploadQty: 1,
    num: 0,
  })

  // 验证规则
  const rules = ref({
    name: [{ required: true, message: '请输入字段名称', trigger: 'blur' }],
    text: [{ required: true, message: '请输入字段内容', trigger: 'blur' }],
    uploadQty: [
      { required: false, message: '请输入上传数量', trigger: 'blur' },
      {
        validator: (rule, value: string, callback) => {
          if (!/^[+]{0,1}(\d+)$/g.test(String(__form.value.uploadQty))) {
            callback(new Error('格式错误'))
          }
          if (__form.value.uploadQty > 10) {
            callback(new Error('最多上传10张'))
          } else {
            callback()
          }
        },
        trigger: 'blur',
      },
    ],
    uploadSize: [
      { required: false, message: '请输入最大尺寸', trigger: 'blur' },
      {
        pattern: /^[+]{0,1}(\d+)$/g,
        message: '格式错误',
        trigger: 'blur',
      },
    ],
    sort: [
      { required: false, message: '请输入字段排序', trigger: 'blur' },
      {
        pattern: /^[+]{0,1}(\d+)$/g,
        message: '格式错误',
        trigger: 'blur',
      },
    ],
  })

  // 弹窗的显示状态
  const visible = ref(props.modelValue)

  // 新增字段内容
  const addText = () => {
    __form.value.contentVos.push({
      val: '',
      id: '',
    })
  }

  // 删除字段内容
  const handleDelFieldContent = (index: number, obj: (typeof __form.value.contentVos)[0]) => {
    __form.value.contentVos.splice(index, 1)
    if (obj.id) {
      if (!__form.value.delContentIds) {
        __form.value.delContentIds = [obj.id]
        return false
      }
      __form.value.delContentIds.push(obj.id)
    }
  }

  // 字段编辑表单组件实例
  const fieldEditFormRef = ref<FormInstance>()

  /**
   * 保存字段
   */
  const saveField = async () => {
    if (![5, 6, 7].includes(__form.value.type)) {
      __form.value.uploadSize = 100
      __form.value.uploadQty = 1
    }
    if (!fieldEditFormRef.value) {
      return false
    }
    try {
      await fieldEditFormRef.value.validate()
      if (![3, 4].includes(__form.value.type)) {
        __form.value.contentVos = []
      }
      emits('updated', _.cloneDeep(__form.value))
      visible.value = false
      emits('update:modelValue', visible.value)
    } catch (e) {
      // 不可删除catch块，否则表单校验失败会导致控制台报错，只有添加了catch块才不会报错，并且在catch里什么都不用做
    }
  }

  /**
   * 取消按钮点击事件
   */
  const onClose = () => {
    visible.value = false
    emits('update:modelValue', visible.value)
  }
  const limitNum = (val, n) => {
    if (val > n) {
      val = n
    } else if (val == 0 && val != '') {
      val = 1
    }
    if (n == 100) {
      __form.value.uploadSize = val
    } else {
      __form.value.uploadQty = val
    }
  }
  watch(
    props,
    (value) => {
      __form.value = _.cloneDeep(value.form)
      visible.value = value.modelValue
    },
    { immediate: true, deep: true },
  )
</script>

<template>
  <div>
    <span>
      <slot></slot>
    </span>

    <!-- 添加/编辑  字段弹窗 -->
    <h-drawer v-model="visible" :width="700" unit="px" :title="props.modalTitle" @close="onClose">
      <el-form
        ref="fieldEditFormRef"
        label-position="top"
        inline-message
        class="modal_form_content"
        :rules="rules"
        :model="__form"
      >
        <!--字段名称-->
        <el-form-item label="字段名称" prop="name">
          <el-input v-model.trim="__form.name" clearable placeholder="请输入名称" />
        </el-form-item>

        <!--字段类型-->
        <el-form-item label="字段类型">
          <el-select v-model="__form.type" placeholder="Select" :disabled="!props.isAdd">
            <el-option
              v-for="item in fieldTypeOptions"
              :key="item.val"
              :label="item.name"
              :value="item.val"
            />
          </el-select>
        </el-form-item>

        <!--字段排序-->
        <el-form-item label="字段排序" prop="sort">
          <el-input v-model.trim="__form.sort" clearable placeholder="请输入字段排序" />
        </el-form-item>

        <!--提示信息-->
        <el-form-item label="提示信息">
          <el-input v-model.trim="__form.tip" clearable placeholder="请输入提示信息" />
        </el-form-item>

        <!--最大尺寸-->
        <el-form-item
          v-if="__form.type === 5 || __form.type === 6 || __form.type === 7"
          label="最大尺寸(MB)"
          class="form-item"
          prop="uploadSize"
        >
          <el-input
            v-model.trim="__form.uploadSize"
            clearable
            placeholder="请输入最大尺寸"
            type="number"
            @input="limitNum(__form.uploadSize, 100)"
            @change="__form.uploadSize ? '' : (__form.uploadSize = 1)"
          />
        </el-form-item>

        <!--上传数量-->
        <el-form-item
          v-if="__form.type === 5 || __form.type === 6 || __form.type === 7"
          label="上传数量"
          prop="uploadQty"
        >
          <el-input
            v-model.trim="__form.uploadQty"
            clearable
            placeholder="请输入数量(最多10张)"
            type="number"
            @input="limitNum(__form.uploadQty, 10)"
            @change="__form.uploadQty ? '' : (__form.uploadQty = 1)"
          />
        </el-form-item>

        <template v-if="__form.type === 4 || __form.type === 3">
          <el-form-item
            v-for="(item, index) in __form.contentVos"
            :key="index"
            :prop="`contentVos[${index}][val]`"
            :rules="rules.text"
            :label="`字段内容${index + 1}`"
          >
            <span class="field_content">
              <el-input
                v-model.trim="item.val"
                clearable
                placeholder="请输入字段内容"
                maxlength="20"
              />
              <div class="btn_group">
                <h-link
                  v-if="__form.contentVos.length > 1"
                  type="error"
                  @click="handleDelFieldContent(index, item)"
                  >删除</h-link
                >
                <h-link v-if="index === 0" @click="addText">添加</h-link>
              </div>
            </span>
          </el-form-item>
        </template>

        <div class="same_line" style="column-gap: 32px">
          <!--是否必填-->
          <el-form-item label="是否必填" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="__form.required" />
              <span v-if="__form.required">是</span>
              <span v-else>否</span>
            </div>
          </el-form-item>

          <!--字段状态-->
          <el-form-item label="字段状态" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="__form.status" :active-value="false" :inactive-value="true" />
              <span v-if="__form.status">禁用</span>
              <span v-else>启用</span>
            </div>
          </el-form-item>
        </div>
      </el-form>
      <template #footer>
        <HButton is-modal type="primary" @click="saveField">保存</HButton>
        <HButton is-modal @click="onClose"> 取消 </HButton>
      </template>
    </h-drawer>
  </div>
</template>

<style scoped lang="scss">
  :deep(.el-button--primary.is-link) {
    color: #007cff;
    margin: 0;

    &:hover {
      color: rgba(#007cff, 0.5);
    }
  }

  // 单选、多选字段内容的表单项
  .field_content {
    display: flex;
    column-gap: 5px;
    align-items: center;
    width: 100%;

    :deep(.el-input) {
      width: 355px;
    }

    .btn_group {
      display: flex;
      column-gap: 5px;
      height: 28px;
      align-items: center;
    }
  }
</style>
